package com.nexusvoice.domain.user.model;

import com.nexusvoice.domain.common.BaseDomainEntity;
import com.nexusvoice.domain.user.constant.OAuthProvider;
import com.nexusvoice.domain.user.constant.UserStatus;
import com.nexusvoice.domain.user.constant.UserType;

import java.time.LocalDateTime;
import java.util.Objects;

/**
 * 用户领域实体
 * 纯净的领域模型，不包含任何技术框架注解
 * 
 * @author NexusVoice
 * @since 2025-09-23
 */
public class User extends BaseDomainEntity {

    private static final long serialVersionUID = 1L;

    // ID字段继承自BaseDomainEntity (Long类型)

    /**
     * 用户登录邮箱
     */
    private String email;

    /**
     * 加密后的用户密码
     */
    private String passwordHash;

    /**
     * 用户昵称
     */
    private String nickname;

    /**
     * 用户头像图片的URL
     */
    private String avatarUrl;

    /**
     * 手机号码
     */
    private String phone;

    /**
     * 用户类型
     */
    private UserType userType;

    /**
     * 账户状态
     */
    private UserStatus status;

    /**
     * 邮箱是否已验证 (0-未验证, 1-已验证)
     */
    private Integer emailVerified;

    /**
     * 最后登录时间
     */
    private LocalDateTime lastLoginAt;

    /**
     * 用户简介
     */
    private String profileBio;

    /**
     * OAuth提供商
     */
    private OAuthProvider oauthProvider;

    /**
     * OAuth用户ID
     */
    private String oauthId;

    /**
     * OAuth用户名
     */
    private String oauthUsername;

    /**
     * OAuth头像URL
     */
    private String oauthAvatarUrl;

    /**
     * OAuth访问令牌
     */
    private String oauthAccessToken;

    /**
     * OAuth刷新令牌
     */
    private String oauthRefreshToken;

    /**
     * OAuth令牌过期时间
     */
    private LocalDateTime oauthTokenExpiresAt;

    /**
     * OAuth绑定时间
     */
    private LocalDateTime oauthBindTime;

    /**
     * OAuth原始数据
     */
    private String oauthRawData;

    // 构造函数
    public User() {
        this.userType = UserType.USER;
        this.status = UserStatus.NORMAL;
        this.emailVerified = 0;
    }

    public User(String email, String passwordHash, String nickname) {
        this();
        this.email = email;
        this.passwordHash = passwordHash;
        this.nickname = nickname;
    }

    // 业务方法

    /**
     * 激活用户账户
     */
    public void activate() {
        if (this.status == UserStatus.PENDING_ACTIVATION) {
            this.status = UserStatus.NORMAL;
        }
    }

    /**
     * 封禁用户
     */
    public void ban() {
        if (this.status != UserStatus.BANNED) {
            this.status = UserStatus.BANNED;
        }
    }

    /**
     * 解封用户
     */
    public void unban() {
        if (this.status == UserStatus.BANNED) {
            this.status = UserStatus.NORMAL;
        }
    }

    /**
     * 验证邮箱
     */
    public void verifyEmail() {
        this.emailVerified = 1;
    }

    /**
     * 更新最后登录时间
     */
    public void updateLastLoginTime() {
        this.lastLoginAt = LocalDateTime.now();
    }

    /**
     * 判断是否为管理员
     *
     * @return true-管理员, false-普通用户
     */
    public boolean isAdmin() {
        return this.userType != null && this.userType.isAdmin();
    }

    /**
     * 判断账户是否正常
     *
     * @return true-正常, false-非正常
     */
    public boolean isAccountNormal() {
        return this.status != null && this.status.isNormal();
    }

    /**
     * 判断是否被封禁
     *
     * @return true-被封禁, false-未被封禁
     */
    public boolean isBanned() {
        return this.status != null && this.status.isBanned();
    }

    /**
     * 判断邮箱是否已验证
     * 
     * @return true-已验证, false-未验证
     */
    public boolean hasEmailVerified() {
        return Integer.valueOf(1).equals(this.emailVerified);
    }

    /**
     * 判断是否为OAuth用户
     *
     * @return true-OAuth用户, false-非OAuth用户
     */
    public boolean isOAuthUser() {
        return oauthProvider != null && oauthId != null;
    }

    /**
     * 判断是否为密码登录用户
     *
     * @return true-密码用户, false-非密码用户
     */
    public boolean isPasswordUser() {
        return passwordHash != null;
    }

    /**
     * 判断是否可以使用密码登录
     *
     * @return true-可以使用密码登录, false-不能使用密码登录
     */
    public boolean canLoginWithPassword() {
        return isPasswordUser();
    }

    /**
     * 判断是否可以使用OAuth登录
     *
     * @return true-可以使用OAuth登录, false-不能使用OAuth登录
     */
    public boolean canLoginWithOAuth() {
        return isOAuthUser();
    }

    /**
     * 绑定OAuth账号
     *
     * @param provider OAuth提供商
     * @param oauthUserId OAuth用户ID
     * @param oauthUsername OAuth用户名
     */
    public void bindOAuth(OAuthProvider provider, String oauthUserId, String oauthUsername) {
        this.oauthProvider = provider;
        this.oauthId = oauthUserId;
        this.oauthUsername = oauthUsername;
        this.oauthBindTime = LocalDateTime.now();
    }

    /**
     * 解绑OAuth账号
     */
    public void unbindOAuth() {
        // 只有当用户有密码时才能解绑OAuth
        if (!isPasswordUser()) {
            throw new IllegalStateException("无法解绑OAuth：用户未设置密码");
        }
        this.oauthProvider = null;
        this.oauthId = null;
        this.oauthUsername = null;
        this.oauthAvatarUrl = null;
        this.oauthAccessToken = null;
        this.oauthRefreshToken = null;
        this.oauthTokenExpiresAt = null;
        this.oauthBindTime = null;
        this.oauthRawData = null;
    }

    /**
     * 更新OAuth令牌
     *
     * @param accessToken 访问令牌
     * @param refreshToken 刷新令牌
     * @param expiresAt 过期时间
     */
    public void updateOAuthTokens(String accessToken, String refreshToken, LocalDateTime expiresAt) {
        this.oauthAccessToken = accessToken;
        this.oauthRefreshToken = refreshToken;
        this.oauthTokenExpiresAt = expiresAt;
    }

    /**
     * 判断OAuth令牌是否过期
     *
     * @return true-已过期, false-未过期
     */
    public boolean isOAuthTokenExpired() {
        if (oauthTokenExpiresAt == null) {
            return true;
        }
        return LocalDateTime.now().isAfter(oauthTokenExpiresAt);
    }

    // Getter and Setter methods (ID方法继承自BaseEntity)
    
    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getPasswordHash() {
        return passwordHash;
    }

    public void setPasswordHash(String passwordHash) {
        this.passwordHash = passwordHash;
    }

    public String getNickname() {
        return nickname;
    }

    public void setNickname(String nickname) {
        this.nickname = nickname;
    }

    public String getAvatarUrl() {
        return avatarUrl;
    }

    public void setAvatarUrl(String avatarUrl) {
        this.avatarUrl = avatarUrl;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public UserType getUserType() {
        return userType;
    }

    public void setUserType(UserType userType) {
        this.userType = userType;
    }

    public UserStatus getStatus() {
        return status;
    }

    public void setStatus(UserStatus status) {
        this.status = status;
    }

    public Integer getEmailVerified() {
        return emailVerified;
    }

    public void setEmailVerified(Integer emailVerified) {
        this.emailVerified = emailVerified;
    }

    public LocalDateTime getLastLoginAt() {
        return lastLoginAt;
    }

    public void setLastLoginAt(LocalDateTime lastLoginAt) {
        this.lastLoginAt = lastLoginAt;
    }

    public String getProfileBio() {
        return profileBio;
    }

    public void setProfileBio(String profileBio) {
        this.profileBio = profileBio;
    }

    public OAuthProvider getOauthProvider() {
        return oauthProvider;
    }

    public void setOauthProvider(OAuthProvider oauthProvider) {
        this.oauthProvider = oauthProvider;
    }

    public String getOauthId() {
        return oauthId;
    }

    public void setOauthId(String oauthId) {
        this.oauthId = oauthId;
    }

    public String getOauthUsername() {
        return oauthUsername;
    }

    public void setOauthUsername(String oauthUsername) {
        this.oauthUsername = oauthUsername;
    }

    public String getOauthAvatarUrl() {
        return oauthAvatarUrl;
    }

    public void setOauthAvatarUrl(String oauthAvatarUrl) {
        this.oauthAvatarUrl = oauthAvatarUrl;
    }

    public String getOauthAccessToken() {
        return oauthAccessToken;
    }

    public void setOauthAccessToken(String oauthAccessToken) {
        this.oauthAccessToken = oauthAccessToken;
    }

    public String getOauthRefreshToken() {
        return oauthRefreshToken;
    }

    public void setOauthRefreshToken(String oauthRefreshToken) {
        this.oauthRefreshToken = oauthRefreshToken;
    }

    public LocalDateTime getOauthTokenExpiresAt() {
        return oauthTokenExpiresAt;
    }

    public void setOauthTokenExpiresAt(LocalDateTime oauthTokenExpiresAt) {
        this.oauthTokenExpiresAt = oauthTokenExpiresAt;
    }

    public LocalDateTime getOauthBindTime() {
        return oauthBindTime;
    }

    public void setOauthBindTime(LocalDateTime oauthBindTime) {
        this.oauthBindTime = oauthBindTime;
    }

    public String getOauthRawData() {
        return oauthRawData;
    }

    public void setOauthRawData(String oauthRawData) {
        this.oauthRawData = oauthRawData;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        User user = (User) o;
        return Objects.equals(id, user.id);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id);
    }

    @Override
    public String toString() {
        return "User{" +
                "id='" + id + '\'' +
                ", email='" + email + '\'' +
                ", nickname='" + nickname + '\'' +
                ", userType=" + userType +
                ", status=" + status +
                ", emailVerified=" + emailVerified +
                ", createdAt=" + createdAt +
                '}';
    }
}
